package com.payment.controller.paynotify;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.payment.entity.common.OrderPaymentManager;
import com.payment.entity.common.UserboundPaymentOrder;
import com.payment.entity.newrequestnotify.request.RequestNotify;
import com.payment.entity.newrequestnotify.response.ResponseNotify;
import com.payment.entity.payresults.WXNotificationpaymentResults;
import com.payment.service.NotificationpaymentService;
import com.payment.service.OrderPaymentManagerService;
import com.payment.service.PartnerService;
import com.payment.utils.Constant;
import com.payment.utils.HttpUtil;
import com.payment.utils.WxPayUtil;
import io.swagger.annotations.Api;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.util.Map;

@RestController
@Api(description = "微信支付回调")
/**
 * 1，使用领科的微信收款账号收款，微信支付回调接口：
 *
 * 2，适用于老的客户：第一版的领科商城，TCL 这种老的客户；
 *
 * 3，更新的数据表为：user_order_payment_manager_t，user_bound_payment_order_t；
 *
 *  4，更新的数据库为：links
 *
 * @author lm
 * @date 2019/11/06
 */
public class WeiXinPayNotifyController {
    private static Logger logger = Logger.getLogger(WeiXinPayNotifyController.class);
    @Autowired
    private OrderPaymentManagerService orderPaymentManagerService;
    @Autowired
    private NotificationpaymentService notificationpaymentService;
    @Autowired
    PartnerService partnerService;
    /*支付方式:1-微信支付，2-paypal支付，3-oceanpay支付*/

    /**
     * 微信支付结果回调
     *
     * @param request
     * @param
     * @return
     */
    @RequestMapping(value = "/wxNotify")
    @CrossOrigin
    public String notify(HttpServletRequest request, HttpServletResponse response) {
        try {
            logger.info("微信支付回调:");
            Map rMap = WxPayUtil.getNotifyResult(request);
            // 向微信输出处理结果，如果成功（SUCCESS），微信就不会继续调用了，否则微信会连续调用8次
            String resXml = rMap.get("resXml") + "";
            logger.info("微信支付回调notify获取的数据：" + rMap.get("resXml") + "");
            String orderId = rMap.get("out_trade_no") + "";
            String result_code = rMap.get("result_code") + "";
            String return_code = rMap.get("return_code") + "";

            //为了从微信拿回来的金额能够直接使用
            String total_fee = rMap.get("total_fee") + "";
            //int fee = Integer.parseInt(total_fee) / 100;
            float fee = Float.parseFloat(total_fee) / 100;
            String payAmount = String.valueOf(fee);

            String appid = rMap.get("appid") + "";
            String bank_type = rMap.get("bank_type") + "";
            String cash_fee = rMap.get("cash_fee") + "";
            String fee_type = rMap.get("fee_type") + "";
            String is_subscribe = rMap.get("is_subscribe") + "";
            String mch_id = rMap.get("mch_id") + "";
            String nonce_str = rMap.get("nonce_str") + "";
            String openid = rMap.get("openid") + "";
            String out_trade_no = rMap.get("out_trade_no") + "";
            String sign = rMap.get("sign") + "";
            String time_end = rMap.get("time_end") + "";
            String trade_type = rMap.get("trade_type") + "";
            String transaction_id = rMap.get("transaction_id") + "";

            //去数据库查询out_trade_no是不是已经入过库
            int count = notificationpaymentService.findCountByOutTradeno(out_trade_no);
            if (count <= 0) {
                //将微信回传的交易记录入库保存下来
                WXNotificationpaymentResults results = new WXNotificationpaymentResults();
                results.setAppid(appid);
                results.setBankType(bank_type);
                results.setCashFee(cash_fee);
                results.setFeeType(fee_type);
                results.setIsSubscribe(is_subscribe);
                results.setMchId(mch_id);
                results.setNonceStr(nonce_str);
                results.setOpenid(openid);
                results.setOutTradeNo(out_trade_no);
                results.setResultCode(result_code);
                results.setReturnCode(return_code);
                results.setSign(sign);
                results.setTimeEnd(time_end);
                results.setTotalFee(total_fee);
                results.setTradeType(trade_type);
                results.setTransactionId(transaction_id);
                notificationpaymentService.insertPaymentResults(results);
            }

            // 判断result_code和return_code同时是SUCCESS就return给北京
            if (result_code.equalsIgnoreCase("SUCCESS") || return_code.equalsIgnoreCase("SUCCESS")) {
                // 查询一下当前out_trade_no单号有没有通知过北京，要是通知过IsNotify肯定是0了，
                //根据微信回调的订单号去数据库查询当前记录是不是已经记录
                logger.info("回调的支付订单号out_trade_no：" + orderId);
                int c = orderPaymentManagerService.findOrderIdByNotify(orderId);
                if (c <= 0) {
                    // 成功就将PayRst设为1；不插入就数据库默认0
                    // 成功就要通知，数据库就记1，不成功就不通知数据库会默认0

                    OrderPaymentManager paymentOrder = new OrderPaymentManager();
                    paymentOrder.setPayRst("success");
                    paymentOrder.setIsNotify("1");
                    paymentOrder.setPayType(Constant.PAY_WEIXIN);
                    paymentOrder.setOrderId(orderId);
                    paymentOrder.setOrderCurrency(fee_type);
                    paymentOrder.setAmount(payAmount);
                    orderPaymentManagerService.updatePayRst(paymentOrder);
                    logger.info("微信支付结果入库完成！");

                    //兼容之前的记录：
                    UserboundPaymentOrder order = new UserboundPaymentOrder();
                    order.setPaymentOrderId(orderId);
                    order.setPayType("2");
                    order.setIsNotify("1");
                    order.setAmount(payAmount);
                    order.setOrderCurrency(fee_type);
                    order.setPayRst("success");
                    orderPaymentManagerService.UpdatePaypalNotify(order);
                    logger.info("微信支付结果入库完成！");
                    //拿到orderId就去做支付结果通知就好
                    //将去北京做支付结果通知的工作交到具体的PaymentResultService处理类中去
                    OrderPaymentManager userOrder = orderPaymentManagerService.queryOrderByOrderId(orderId, payAmount);
                    if (userOrder == null) {
                        logger.info("OrderPaymentManager表中没有查询到需要去做支付结果通知的数据！");
                        UserboundPaymentOrder paymentManagerOrder = orderPaymentManagerService.queryPaymentOrderByOrderId(orderId, payAmount);
                        if (paymentManagerOrder == null) {
                            logger.info("UserboundPaymentOrder表中没有查询到需要去做支付结果通知的数据！");
                        } else {
                            String partnerCode = paymentManagerOrder.getPartnerCode();
                            String orderCode = paymentManagerOrder.getOrderId();
                            String deviceId = paymentManagerOrder.getDeviceId();
                            String deviceType = paymentManagerOrder.getDeviceType();
                            String Amount = paymentManagerOrder.getAmount();
                            logger.info("查询到的订单orderId是:" + orderCode + ";DeviceId是:" + deviceId + ";DeviceType是:" + deviceType + ";payAmount是：" + payAmount);
                            String secret = partnerService.findSecretByPartnerCode(partnerCode);

                            RequestNotify notify = new RequestNotify();
                            notify.setDeviceId(deviceId);
                            notify.setOrderId(orderCode);
                            notify.setPayAmount(Amount);
                            notify.setPayType(Constant.PAY_WEIXIN);
                            notify.setSecret(secret);
                            notify.setPartnerCode(partnerCode);
                            // 开始组装json
                            String requestStr = JSON.toJSONString(notify);
                            logger.info("请求北京的接口请求报文：" + requestStr);
                            String url = Constant.requestURI + Constant.iot_notify;
                            // 发送post请求，并接收返回结果
                            String returnStr = HttpUtil.httpPost(url, requestStr);
                            logger.info("北京回复的下发接口响应报文：" + returnStr);
                            ResponseNotify re = JSONArray.parseObject(returnStr, ResponseNotify.class);

                            if (re != null) {
                                if (true == Constant.RET_CODE_0000.equalsIgnoreCase(re.getRetCode())) {
                                    logger.info("同步成功");
                                    OrderPaymentManager paymentManager = new OrderPaymentManager();
                                    paymentManager.setIsNotify("0");
                                    paymentManager.setOrderId(orderId);
                                    paymentManager.setAmount(payAmount);
                                    orderPaymentManagerService.updateIsNotifyOrderT(paymentManager);
                                    logger.info("UserboundPaymentOrder数据库更新完成！");
                                } else {
                                    logger.info("同步不成功：" + re.getResultInfo());
                                }
                            } else {
                                logger.info("响应报文为null");
                            }
                        }

                    } else {
                        String partnerCode = userOrder.getPartnerCode();
                        String orderCode = userOrder.getOrderId();
                        String deviceId = userOrder.getDeviceId();
                        String deviceType = userOrder.getDeviceType();
                        String amount = userOrder.getAmount();
                        logger.info("查询到的订单orderId是:" + orderCode + ";DeviceId是:" + deviceId + ";DeviceType是:" + deviceType + ";payAmount是：" + amount);
                        String secret = partnerService.findSecretByPartnerCode(partnerCode);

                        RequestNotify notify = new RequestNotify();
                        notify.setDeviceId(deviceId);
                        notify.setOrderId(orderCode);
                        notify.setPayAmount(amount);
                        notify.setPayType(Constant.PAY_WEIXIN);
                        notify.setSecret(secret);
                        notify.setPartnerCode(partnerCode);
                        // 开始组装json
                        String requestStr = JSON.toJSONString(notify);
                        logger.info("请求北京的接口请求报文：" + requestStr);
                        String url = Constant.requestURI + Constant.iot_notify;
                        // 发送post请求，并接收返回结果
                        String returnStr = HttpUtil.httpPost(url, requestStr);
                        logger.info("北京回复的下发接口响应报文：" + returnStr);
                        ResponseNotify re = JSONArray.parseObject(returnStr, ResponseNotify.class);

                        if (re != null) {
                            if (true == Constant.RET_CODE_0000.equalsIgnoreCase(re.getRetCode())) {
                                logger.info("同步成功");
                                OrderPaymentManager paymentManager = new OrderPaymentManager();
                                paymentManager.setIsNotify("0");
                                paymentManager.setOrderId(orderId);
                                paymentManager.setAmount(payAmount);
                                orderPaymentManagerService.updateIsNotify(paymentManager);
                                logger.info("OrderPaymentManager数据库更新完成！");
                            } else {
                                logger.info("同步不成功：" + re.getResultInfo());
                            }
                        } else {
                            logger.info("响应报文为null");
                        }
                    }

                }

            }
            //回复微信说：你不要在发信息给我，我收到了
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
